package com.twb.fileCenter.sftp;

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;

/**
 * @ClassName: SftpUtil
 * @Description: sftp工具类
 * @author DSY
 * @date 2017年4月19日 下午5:34:37
 */
@Component
public class SftpUtil {
	private static Logger logger = LoggerFactory.getLogger(SftpUtil.class);
	private static ChannelSftp sftp;
	private static Session session;
	@Autowired
	private SftpConfigProperties configProperties;

	private static SftpConfigProperties config;

	@PostConstruct
	public void init() {
		config = configProperties;
	}

	/**
	 * 连接sftp服务器
	 */
	public static void login() {
		boolean islogin = false;
		if (sftp != null) {
			if (sftp.isConnected()) {
				islogin = true;
			}
		}
		if (session != null) {
			if (session.isConnected()) {
				islogin = true;
			}
		}
		if(islogin) {
			return;
		}
		
		try {
			JSch jsch = new JSch();
			if (config.getPrivateKey() != null) {
				jsch.addIdentity(config.getPrivateKey());// 设置私钥
			}

			session = jsch.getSession(config.getUsername(), config.getHost(), config.getPort());

			if (config.getPassword() != null) {
				session.setPassword(config.getPassword());
			}
			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");

			session.setConfig(config);
			session.connect();

			Channel channel = session.openChannel("sftp");
			channel.connect();

			sftp = (ChannelSftp) channel;
		} catch (JSchException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭连接 server
	 */
	public static void logout() {
		if (sftp != null) {
			if (sftp.isConnected()) {
				sftp.disconnect();
			}
		}
		if (session != null) {
			if (session.isConnected()) {
				session.disconnect();
			}
		}
	}

	/**
	 * @Title: uploadFile
	 * @Class: FtpUtil.java
	 * @Package: com.tw.common.ftp
	 * @Description:上传文件
	 * @param filepath
	 * @param filename
	 * @param inputStream
	 * @return
	 * @throws SftpException 
	 * @AuthorOriginally DSY
	 * @date 2017年4月12日 下午3:42:26
	 */
	public static Boolean uploadFile(String filepath, String filename, InputStream inputStream) throws SftpException {
		try {
			login();
			try {   
	            sftp.cd(filepath);
	        } catch (SftpException e) { 
	            //目录不存在，则创建文件夹
	            String [] dirs=filepath.split("/");
	            String tempPath="";
	            for(String dir:dirs){
	            	if(null== dir || "".equals(dir)) continue;
	            	tempPath+="/"+dir;
	            	try{ 
	            		sftp.cd(tempPath);
	            	}catch(SftpException ex){
	            		sftp.mkdir(tempPath);
	            		sftp.cd(tempPath);
	            	}
	            }
	        }  
	        sftp.put(inputStream, filename);  //上传文件
		} catch (Exception e) {
			logger.error("文件上传失败",e);
		}finally {
			logout();
		}
		
		return true;
	}

	/**
	 * @Title: downFile
	 * @Class: FtpUtil.java
	 * @Package: com.tw.common.ftp
	 * @Description:下载文件
	 * @param ftpUrl
	 * @return
	 * @AuthorOriginally DSY
	 * @date 2017年4月12日 下午4:31:29
	 */
	public static Boolean downFile(String fileServerPath, String ftpUrl, String localPath) {
		boolean result = false;
		try {
			login();
			String filepath = fileServerPath + ftpUrl.substring(0, ftpUrl.lastIndexOf("/"));
			String filename = ftpUrl.substring(ftpUrl.lastIndexOf("/") + 1);
			if (filepath != null && !"".equals(filepath)) {  
	            sftp.cd(filepath);  
	        }  
	        File file = new File(localPath);  
	        sftp.get(filename, new FileOutputStream(file)); 
	        result = true;
		} catch (Exception e) {
			logger.error("文件下载失败",e);
		}finally {
			logout();
		}
		return result;
	}

	/**
	 * @Title: deleteFile
	 * @Class: FtpUtil.java
	 * @Package: com.tw.common.ftp
	 * @Description:删除文件
	 * @param serverpath
	 * @param fileName
	 * @return
	 * @AuthorOriginally DSY
	 * @date 2017年4月19日 下午5:32:48
	 */
	public static boolean deleteFile(String serverpath, String fileName) {
		// 初始表示下载失败
		boolean success = false;
		try {
			login();
			sftp.cd(serverpath);  
	        sftp.rm(fileName); 
	        success = true;
		} catch (Exception e) {
			logger.error("文件删除失败",e);
		} finally {
			logout();
		}
		return success;
	}
	 /** 
     * 列出目录下的文件 
     * @param directory 要列出的目录
     */  
    public Vector<?> listFiles(String directory) throws SftpException { 
    	Vector<?> vector = null;
    	try {
			login();
			vector = sftp.ls(directory);
		} catch (Exception e) {
			logger.error("文件删除失败",e);
		} finally {
			logout();
		}
        return vector;  
    }
    
    /**
     * @Title createAndChangeDirectory
     * @Description 创建文件夹
     * @param filepath
     * @return
     * @throws IOException
     * @AuthorOriginally 杜顺亚
     * @date 2021年4月28日 下午5:11:41
     */
    public static boolean createAndChangeDirectory(String filepath) throws IOException {
		boolean existFlag = false;
		try {
			login();
			try {   
	            sftp.cd(filepath);
	        } catch (SftpException e) { 
	            //目录不存在，则创建文件夹
	            String [] dirs=filepath.split("/");
	            String tempPath="";
	            for(String dir:dirs){
	            	if(null== dir || "".equals(dir)) continue;
	            	tempPath+="/"+dir;
	            	try{ 
	            		sftp.cd(tempPath);
	            	}catch(SftpException ex){
	            		sftp.mkdir(tempPath);
	            		sftp.cd(tempPath);
	            	}
	            }
	        }  
		} catch (Exception e) {
			logger.error("文件夹创建失败",e);
		}finally {
			logout();
		}
		return existFlag;
	}
    
    /**
	 * @Title: copyFile
	 * @Class: FtpUtil.java
	 * @Package: com.tw.common.ftp
	 * @Description:复制文件
	 * @param from
	 * @param to
	 * @return
	 * @AuthorOriginally DSY
	 * @date 2017年4月19日 下午5:51:14
	 */
	public static boolean copyFile(String from, String to) {
        boolean copyFalg = false;
        try {
			login();
			//待实现
		} catch (Exception e) {
			logger.error("文件夹创建失败",e);
		}finally {
			logout();
		}
    		
        return copyFalg;

    }
}
